package com.easymin.weixin.common.api;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.easymin.weixin.controller.v4.ResultTransport;
import com.easymin.weixin.entity.passenger.Passenger;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@Component
public class ZhuanXianApi {

    @Value("${module.zhuanxian.url}")
    private String zhuanxianApiGateway;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private PassengerApi passengerApi;

    @Autowired
    private DaijiaApi daijiaApi;

    /**
     * 查询某条线路的反向线路
     */
    public static final String FIND_ReturnLine = "api/line/findReturnLine.json?lineId={lineId}&appKey={appKey}";
    /**
     * 根据经纬度查询专线类型.
     */
    public static final String FIND_LINEALL =
            "api/order/wxQueryLineAll.json?lat={lat}&lng={lng}&appKey={appKey}";
    /**
     * 根据线路ID查询收费.
     */
    public static final String FIND_BYLINEID = "api/zhuanxian/getPrice.json?lineId={lineId}";
    /**
     * 取消订单.
     */
    public static final String CANCEL_ZHUANXIAN_ORDER =
            "api/order/passengerCancel.json?orderId={orderId}&cause={cause}&appKey={appKey}";
    /**
     * 下单.
     */
    public static final String CREATE_ZXORDER =
            "api/order/create.json?orderType={orderType}&passengerId={passengerId}"
                    + "&passengerName={passengerName}&passengerPhone={passengerPhone}&lineId={lineId}"
                    + "&companyId={companyId}&companyName={companyName}&channelName={channelName}"
                    + "&startAddress={startAddress}&startLat={startLat}&startLng={startLng}"
                    + "&endAddress={endAddress}&endLat={endLat}&endLng={endLng}&startTime={startTime}"
                    + "&serverDeadTime={serverDeadTime}&budgetPay={budgetPay}&couponId={couponId}"
                    + "&peopleNumber={peopleNumber}&memo={memo}&takeDeliveryName={takeDeliveryName}"
                    + "&takeDeliveryPhone={takeDeliveryPhone}&serverAddress={serverAddress}&appKey={appKey}";

    /**
     * 统计未完成订单.
     */
    public static final String FIND_RUNNINGS =
            "api/order/findByParam?passengerId={passengerId}&allstatus={allstatus}&appKey={appKey}";
    /**
     * 根据开始 、结束地点查询路线.
     */
    public static final String FIND_LINEALLBYSE =
            "api/line/findStartEndByLine?startCity={startCity}&endCity={endCity}&appKey={appKey}";
    /**
     * 查询单个订单.
     */
    public static final String FIND_ONE = "api/order/findOne?orderId={orderId}&appKey={appKey}";
    /**
     * 评价订单.
     */
    public static final String ORDER_REVIEW =
            "api/orderReview/review.json?orderId={orderId}&content={content}"
                    + "&score={score}&appKey={appKey}";

    /**
     * 创建客户.
     */
    public static final String CREAT_PASSENGER =
            "api/passengers/v4/create.json?phone={phone}&companyId={companyId}"
                    + "&companyName={companyName}&appKey={appKey}";

    public static final String GET_ZX_WX_PREPAYID =
            "api/zhuanxian/wx/prepayId_jsapi.json?orderId={orderId}&openid={openid}";
    /**
     * 预算费用.
     */
    public static final String BUDGETED_EXPENXE =
            "api/zhuanxian/wxBudgetedExpense ?areaId={areaId}&startLat={startLat}"
                    + "&startLng={startLng}&endLat={endLat}&endLng={endLng}";


    public static final String COUNT_NOTPAYAMOUNTS =
            "api/order/countByPassengerId.json?passengerId={passengerId}&appKey={appKey}";

    /**
     * V5分页获取专线订单
     */
    public static final String GET_ORDERS_V5 = "api/order/findOrderByPassenger";

    /**
     * 获取该线路的反向线路
     * @param lineId
     * @return
     */
    public JSONObject findReturnLine(Long lineId, String appKey){
        String url = buildApi(FIND_ReturnLine);
        String response = restTemplate.getForObject(url,String.class,lineId,appKey);
        JSONObject jsonObject = JSON.parseObject(response);
        return jsonObject;
    }

    /**
     * 查询所有路线.
     *
     * @param lat    纬度
     * @param lng    经度
     * @param appKey 系统key
     * @return JSONArray
     */
    public JSONArray findLineAll(Double lat, Double lng, String appKey) {
        String response =
                restTemplate.getForObject(buildApi(FIND_LINEALL), String.class, lat, lng, appKey);


        JSONObject jsonObject = JSON.parseObject(response);
        JSONArray jsonArray = jsonObject.getJSONArray("data");
        return jsonArray;
    }

    /**
     * V5分页查询所有线路地址
     */
    private static final String FIND_LINES_BY_PAGE_V5 = "api/line/findLineByParams?appKey={appKey}&serverUrl={serverUrl}";

    private static final String FIND_END_BY_START = "api/line/findEndInfoByStartInfo?appKey={appKey}&serverUrl={serverUrl}&startCity={startCity}&startAddress={startAddress}";

    /**
     * V5按需查询所有线路
     *
     * @param keyWord 关键词
     * @param appKey  系统key
     * @param server  系统地址
     * @param page    页码
     * @param rows    条数
     * @return
     */
    public JSONObject findLinesByParamsV5(String keyWord, String appKey, String server, Integer page, Integer rows) {
        String url = buildApi(FIND_LINES_BY_PAGE_V5);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("appKey", appKey);
        params.put("serverUrl", server);

        // 有关键词
        if (null != keyWord && !keyWord.isEmpty()) {
            url += "&keyWord={keyWord}";
            params.put("keyWord", keyWord);
        }

        // 这里页码和条数一般都是以一对出现，所以这里将两个放在一起
        if (null != page && null != rows) {
            url += "&page={page}";
            params.put("page", page);

            url += "&rows={rows}";
            params.put("rows", rows);
        }
        //微信公众号请求标识
        params.put("isWX", 1);
        url += "&isWX={isWX}";
        String response = restTemplate.getForObject(url, String.class, params);
        if (null == response) {
            return null;
        }
        JSONObject data = JSONObject.parseObject(response);
        int code = data.getIntValue("code");
        if (code != 0) {
            return null;
        }
        return data;
    }

    /**
     * 根据起点查询终点
     *
     * @param startCity    起点城市
     * @param startAddress 起点地址
     * @param appKey       系统key
     * @param server       系统地址
     * @param page         页码
     * @param rows         条数
     * @return
     */
    public JSONObject findEndByStart(String startCity, String startAddress, String appKey, String server, Integer page, Integer rows) {
        String url = buildApi(FIND_END_BY_START);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("appKey", appKey);
        params.put("serverUrl", server);
        params.put("startCity", startCity);
        params.put("startAddress", startAddress);

        // 这里页码和条数一般都是以一对出现，所以这里将两个放在一起
        if (null != page && null != rows) {
            url += "&page={page}";
            params.put("page", page);

            url += "&rows={rows}";
            params.put("rows", rows);
        }

        String response = restTemplate.getForObject(url, String.class, params);

        if (null == response) {
            return null;
        }

        JSONObject data = JSONObject.parseObject(response);
        int code = data.getIntValue("code");

        if (code != 0) {
            return null;
        }
        return data;
    }

    /**
     * 查询线路.
     *
     * @param startCity 开始城市
     * @param endCity   结束城市
     * @param appKey    系统key
     */

    public JSONArray findLineAllByCity(String startCity, String endCity, String appKey) {
        String response = restTemplate.getForObject(
                buildApi(FIND_LINEALLBYSE), String.class, startCity, endCity, appKey);

        JSONObject jsonObject = JSON.parseObject(response);
        JSONArray jsonArray = jsonObject.getJSONArray("data");

        return jsonArray;
    }

    /**
     * 预算费用.
     *
     * @param server   服务地址
     * @param areaId   收费id
     * @param startLat 开始纬度
     * @param startLng 开始经度
     * @param endLat   结束纬度
     * @param endLng   结束经度
     * @return JSONObject
     */
    public JSONObject budgetedExpense(String server, Long areaId, Double startLat, Double startLng,
                                      Double endLat, Double endLng) {
        String response =
                restTemplate.getForObject(buildApiDaijia(server, BUDGETED_EXPENXE), String.class, areaId,
                        startLat, startLng, endLat, endLng);


        JSONObject jsonObject = JSON.parseObject(response);

        return jsonObject;
    }

    /**
     * 根据线路ID查询收费.
     *
     * @param sever  服务地址
     * @param lineId 线路id
     * @return JSONObject
     */
    public JSONObject findBylineId(String sever, Long lineId) {
        String response =
                restTemplate.getForObject(buildApiDaijia(sever, FIND_BYLINEID), String.class, lineId);

        JSONObject jsonObject = JSON.parseObject(response);

        return jsonObject;
    }

    /**
     * 专线下单.
     *
     * @param server            服务地址
     * @param appKey            系统key
     * @param orderType         订单类型
     * @param passengerId       客户id
     * @param passengerPhone    客户手机
     * @param lineId            线路id
     * @param startAddress      开始地点
     * @param startLat          开始地纬度
     * @param startLng          开始地经度
     * @param endAddress        结束地点
     * @param endLat            结束地纬度
     * @param endLng            结束地经度
     * @param startTime         开始时间
     * @param budgetPay         预算费用
     * @param couponId          优惠券id
     * @param peopleNumber      人数
     * @param memo              备注
     * @param takeDeliveryName  收货人名称
     * @param takeDeliveryPhone 收货人电话
     * @param ack               ack
     * @param lat               定位纬度
     * @param lng               定位经度
     * @param openId            微信id
     */

    public JSONObject makeAnZhuanxianAppointmentV4(String server, String appKey, String orderType,
                                                   Long passengerId, String passengerPhone, Long lineId, String startAddress, Double startLat,
                                                   Double startLng, String endAddress, Double endLat, Double endLng, Long startTime,
                                                   Double budgetPay, Long couponId, Long peopleNumber, String memo, String takeDeliveryName,
                                                   String takeDeliveryPhone, String ack, Double lat, Double lng, String openId) {

        String passengerName = null;
        Long companyId = null;
        Long passengerCompanyId = null;
        String companyName = null;
        String channelName = null;
        if (StringUtils.isNotBlank(openId)) {
            channelName = "微信预约";
        } else {
            channelName = "网站预约";
        }
        String service = daijiaApi.findErrandSetting(server);
        JSONObject jsonObject1 = JSON.parseObject(service);
        Integer serverDeadTime = jsonObject1.getInteger("bookTimeZhuanxian");


        Passenger passenger = passengerApi.findOne(passengerPhone, appKey);
        if (passenger != null) {
            passengerName = passenger.getName();
            passengerCompanyId = passenger.getCompanyId();
            passengerId = passenger.getId();
            JSONObject compay =
                    daijiaApi.getCompanyIdAndName(server, ack, passengerCompanyId, lng, lat);
            JSONObject jsonObject2 = compay.getJSONObject("data");

            companyId = jsonObject2.getLong("companyId");
            companyName = jsonObject2.getString("companyName");
        } else {
            JSONObject compay =
                    daijiaApi.getCompanyIdAndName(server, ack, null, lng, lat);
            JSONObject jsonObject2 = compay.getJSONObject("data");

            companyId = jsonObject2.getLong("companyId");
            companyName = jsonObject2.getString("companyName");

        }
        String response =
                restTemplate.postForObject(buildApi(CREATE_ZXORDER), null, String.class, orderType,
                        passengerId, passengerName, passengerPhone, lineId, companyId, companyName,
                        channelName, startAddress, startLat, startLng, endAddress, endLat, endLng, startTime,
                        serverDeadTime, budgetPay, couponId, peopleNumber, memo, takeDeliveryName,
                        takeDeliveryPhone, server, appKey);

        JSONObject jsonObject = JSON.parseObject(response);

        return jsonObject;
    }


    /**
     * 查询未完成订单.
     *
     * @param passengerId 客户id
     * @param appKey      系统key
     * @return JSONArray
     */
    public JSONArray findRunning(Long passengerId, String appKey) {

        Map<String, String> kv = new HashMap<String, String>();
        kv.put("passengerId", String.valueOf(passengerId));
        kv.put("allstatus", "0,1,2,3,4");
        kv.put("appKey", appKey);

        String result = restTemplate.getForObject(buildApi(FIND_RUNNINGS), String.class, kv);
        JSONObject object = JSON.parseObject(result);
        int code = object.getInteger("code");
        JSONArray jsonArray = null;
        if (code == 0) {
            JSONObject json = object.getJSONObject("data");
            jsonArray = json.getJSONArray("rows");
        }
        return jsonArray;
    }


    private String buildApiDaijia(String server, String api) {

        StringBuilder builder = new StringBuilder();

        String daijiaServer = StringUtils.trimToEmpty(server).toLowerCase();
        if (daijiaServer.startsWith("www")) {
            builder.append("https://");
        } else if (!daijiaServer.startsWith("http://") && !daijiaServer.startsWith("https://")) {
            builder.append("http://");
        }
        builder.append(daijiaServer);
        if (!daijiaServer.endsWith("/")) {
            builder.append("/");
        }

        if (StringUtils.isNotBlank(api)) {
            builder.append(api);
        }

        return builder.toString();
    }

    private String buildApi(String api) {
        StringBuilder builder = new StringBuilder();
        builder.append(zhuanxianApiGateway);
        if (!zhuanxianApiGateway.endsWith("/")) {
            builder.append("/");
        }
        builder.append(api);

        return builder.toString();
    }

    /**
     * 专线销单,并且退款.
     *
     * @param orderId 订单id
     * @param cause   销单理由
     * @param appKey  系统key
     */

    public JSONObject cancelZhuanxianOrder(long orderId, String cause, String appKey) {

        String response = restTemplate.postForObject(
                buildApi(CANCEL_ZHUANXIAN_ORDER), null, String.class, orderId, cause, appKey);

        JSONObject jsonObject = JSON.parseObject(response);

        return jsonObject;
    }

    /**
     * 查询专线订单.
     *
     * @param appKey  系统key
     * @param orderId 订单id
     */

    public JSONObject findZhuanxianOrder(String appKey, long orderId) {
        String response = restTemplate.getForObject(buildApi(FIND_ONE), String.class, orderId, appKey);

        JSONObject jsonObject = JSON.parseObject(response);

        return jsonObject;
    }

    /**
     * 评价订单.
     *
     * @param orderId 订单id
     * @param score   评价等级
     * @param content 内容
     * @param appKey  系统key
     * @return JSONObject
     */
    public JSONObject review(Long orderId, Double score, String content, String appKey) {

        String response =
                restTemplate.postForObject(buildApi(ORDER_REVIEW), null, String.class, orderId, content,
                        score, appKey);

        JSONObject jsonObject = JSON.parseObject(response);

        return jsonObject;
    }

    /**
     * 获取专线微信预支付.
     *
     * @param server  系统地址
     * @param orderId 订单id
     * @param openid  微信id
     * @return JSONObject
     */
    public JSONObject getZxWxPrepayId(String server, Long orderId, String openid) {

        String response =
                restTemplate.getForObject(buildApiDaijia(server, GET_ZX_WX_PREPAYID), String.class,
                        orderId, openid);

        return JSON.parseObject(response);
    }

    /**
     * 专线完成结算.
     *
     * @param address 系统地址
     * @param orderId 订单id
     * @param payType 支付类型
     * @param who     支付人
     * @return ResultTransport
     */
    public ResultTransport finishTaskZhuanxian(String address, Long orderId, String payType,
                                               String who) {
        StringBuilder builder = new StringBuilder();
        builder.append(buildApiDaijia(address,
                "api/zhuanxian/finishTask.json?orderId={orderId}&payType={payType}&who={who}"));
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("orderId", orderId);
        map2.put("payType", payType);
        if (StringUtils.isNotBlank(who)) {
            map2.put("who", who);
            builder.append("&who={who}");
        }
        String result = restTemplate.postForObject(builder.toString(), null, String.class, map2);
        ResultTransport parseObject = JSON.parseObject(result, ResultTransport.class);

        return parseObject;


    }

    /**
     * 实时获取专车订单是否被结算.
     *
     * @param address 系统地址
     * @param orderId 订单id
     * @return Map
     */
    public Map<String, Object> checkTaskZhuanxian(String address, Long orderId) {

        Map<String, Object> map = new HashMap<String, Object>();
        StringBuilder builder = new StringBuilder();
        builder.append(buildApiDaijia(address, "api/zhuanxian/checkTask.json?orderId={orderId}"));
        String result = restTemplate.getForObject(builder.toString(), String.class, orderId);
        JSONObject jsonObject = JSON.parseObject(result);
        Integer code = jsonObject.getInteger("code");
        if (code == 0) {
            map.put("code", 0);
            map.put("data", jsonObject.getBoolean("data"));
            map.put("msg", jsonObject.getString("message"));
        } else {
            map.put("code", -1);
            map.put("msg", jsonObject.getString("message"));
            System.err.println(jsonObject.getString("message"));
        }
        return map;
    }

    /**
     * 专车订单客户端支付所需数据.
     *
     * @param address 系统地址
     * @param orderId 订单id
     * @return Map
     */
    public Map<String, Object> clientPayDataZhuanxian(String address, Long orderId) {
        Map<String, Object> map = new HashMap<String, Object>();
        StringBuilder builder = new StringBuilder();
        builder.append(buildApiDaijia(address, "api/zhuanxian/clientPayData.json?orderId={orderId}"));
        String result = restTemplate.getForObject(builder.toString(), String.class, orderId);
        JSONObject jsonObject = JSON.parseObject(result);
        Integer code = jsonObject.getInteger("code");
        JSONObject jsonObject2 = jsonObject.getJSONObject("data");
        if (code == 0) {
            map.put("code", 0);
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("id", orderId);
            data.put("realCash", jsonObject2.getDouble("realCash"));
            data.put("guoluMoney", jsonObject2.getDouble("guoluMoney"));
            data.put("yuanchengMoney", jsonObject2.getDouble("yuanchengMoney"));
            data.put("otherMoney", jsonObject2.getDouble("otherMoney"));
            data.put("preyMoney", jsonObject2.getDouble("preyMoney"));
            data.put("couponMoney", jsonObject2.getDouble("couponMoney"));
            data.put("payMoney", jsonObject2.getDouble("payMoney"));
            data.put("weixinPay", jsonObject2.getBoolean("weixinPay"));
            data.put("aliPay", jsonObject2.getBoolean("aliPay"));
            data.put("overdraw", jsonObject2.getBoolean("overdraw"));
            data.put("randomRedPacket", jsonObject2.getDouble("randomRedPacket"));
            map.put("data", data);
            map.put("msg", jsonObject.getString("message"));
        } else {
            map.put("code", -1);
            map.put("msg", jsonObject.getString("message"));
            System.err.println(jsonObject.getString("message"));
        }
        return map;
    }

    public Long countNotPayAmounts(Long passengerId, String appKey) {
        Long num = 0L;
        try {
            Map<String, String> kv = new HashMap<String, String>();

            kv.put("passengerId", String.valueOf(passengerId));
            kv.put("appKey", appKey);

            String result = restTemplate.getForObject(buildApi(COUNT_NOTPAYAMOUNTS), String.class, kv);

            JSONObject jo = JSON.parseObject(result);

            if (jo.getIntValue("code") == 0) {
                num = jo.getLongValue("data");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return num;
    }

    /**
     * 微信V5分页获取订单
     *
     * @param
     * @param passengerId 乘客id
     * @param page        页码
     * @param rows        数据量
     * @param appKey      系统key
     * @return
     * @throws Exception
     */
    public Map<String, Object> getOrdersV5(Long passengerId,
                                           Integer page, Integer rows, String appKey) throws Exception {

        Map<String, Object> returnMap = new HashMap<String, Object>();

        String api = GET_ORDERS_V5
                + "?passengerId={passengerId}"
                + "&page={page}"
                + "&rows={rows}"
                + "&appKey={appKey}";

        String rs = restTemplate.getForObject(buildApi(api), String.class, passengerId, page, rows, appKey);
        JSONObject json = JSONObject.parseObject(rs);
        if (json.getIntValue("code") != 0) {
            throw new RuntimeException();
        }

        JSONObject data = json.getJSONObject("data");
        returnMap.put("total", data.getInteger("total"));
        returnMap.put("rows", data.getJSONArray("rows"));
        return returnMap;
    }

    /**
     * v5获取当个订单
     */
    private static final String GET_ORDER_BY_ID_V5 = "api/order/findByOrderId";

    /**
     * v5获取当个订单
     *
     * @param appKey
     * @param orderId
     * @return
     */
    public JSONObject getOrderByIdV5(String appKey, Long orderId) {
        try {
            String api = GET_ORDER_BY_ID_V5 + "?appKey={appKey}&orderId={orderId}";
            String rs = restTemplate.getForObject(buildApi(api), String.class, appKey, orderId);
            JSONObject json = JSONObject.parseObject(rs);
            if (json.getIntValue("code") != 0) {
                return null;
            }
            return json;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * V5获取订单评价
     */
    private static final String GET_ORDER_REVIEW_V5 = "api/orderReview/findReview.json";

    /**
     * V5获取订单评价
     *
     * @param appKey
     * @param orderId
     * @return
     */
    public JSONObject getReviewV5(String appKey, Long orderId) {
        try {
            String api = GET_ORDER_REVIEW_V5 + "?orderId={orderId}&appKey={appKey}";

            String rs = restTemplate.getForObject(buildApi(api), String.class, orderId, appKey);

            JSONObject json = JSONObject.parseObject(rs);
            if (null != json && json.getIntValue("code") == 0) {
                return json;
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
